// UIManager.ts

import { _decorator, Canvas, Component, director, error, game,instantiate,Layers,Node, Prefab, resources, UITransform, Vec2, Vec3, view, warn, Widget } from "cc";

import View from "./BaseView";
import { ScreenAdapter } from "../ScreenAdpater";
import BaseView from "./BaseView";
import { LogMgr } from "../log/LogMgr";
import { Tips } from "../../game/ui/components/Tips";

const { ccclass } = _decorator;
@ccclass
export default class UIMgr extends Component {

    private static instance: UIMgr = null;

    // // UI层级节点
    // private mainLayer: Node = null; // Main层
    // private popLayer: Node = null; // Pop层
    // private tipsLayer: Node = null; // Tips层
    // private marqueeLayer: Node = null; // 走马灯层
    // private topLayer: Node = null; // 走马灯层

    // // UI栈
    // private mainStack: View[] = []; // Main层栈
    // private popStack: View[] = []; // Pop层栈
    // private tipsStack: View[] = []; // Tips层栈
    // private marqueeStack: View[] = []; // 走马灯层栈
    // private topStack: View[] = []; // 走马灯层栈

    layers:Map<string,Node> = new Map()
    layerStacks:Map<string,View[]> = new Map()
    beforeShowFun:(layerNode:Node,showView:BaseView,stack:BaseView[])=>void = null;



    public static get ins(): UIMgr {
        if (!this.instance) {
            // let canvasNode = new Node("UI_Canvas")
            // canvasNode.layer = Layers.Enum.UI_2D
            // let size = view.getDesignResolutionSize()
            // canvasNode.setPosition(new Vec3(size.x/2,size.y/2,0))
            // // canvasNode.setPosition(new Vec3(0,0,0))
            // canvasNode.addComponent(Canvas)
            // let widget = canvasNode.addComponent(Widget)
            // widget.left = 0;
            // widget.right = 0;

            // // 设置 Widget 的 top 和 bottom 为 0，实现垂直布满
            // widget.top = 0;
            // widget.bottom = 0;

            // // 设置 Widget 的对齐方式为水平和垂直都对齐
            // widget.isAlignLeft = true;
            // widget.isAlignRight = true;
            // widget.isAlignTop = true;
            // widget.isAlignBottom = true;




            // let mgr = canvasNode.addComponent(UIMgr)
            // canvasNode.addComponent(ScreenAdapter)
            // // 更新 Widget
            // widget.updateAlignment();
            // director.addPersistRootNode(canvasNode)
            // this.instance = mgr;
            error("还未初始化就进行获取！")
        }
        return this.instance;
    }

    //ui预制件的根目录，可以根据名找到预制件
    prefabRootPath = ""
    viewInfos:{
        [name:string]:{
            prefabPath: string, // 预制件路径
            layer: string, // 所属层级
            script: string, // 脚本名称
            package:string,//所属分包
            single:boolean,//是否是单例，单例的话只能有一个当前视图存在
            [key:string]:any
        }
    }

    tipsLayerName:string = ""
    tipsLayerNode:Node = null
    tipsPrefab:Prefab = null
    

    // 初始化UI层级
    public static init(rootNode:Node,tipsLayerName:string) {

        let designSize = view.getDesignResolutionSize()
        // let screenWidth: number = designSize.width * view.getScaleX();
        // let screenHeight: number = designSize.height * view.getScaleY();
        view.getCanvasSize()
        // Global.inst.screenSize = new Size(screenWidth, screenHeight);
        // rootNode.getComponent(UITransform).setContentSize(screen.width, screen.height);
        // view.setDesignResolutionSize(Math.abs(screenWidth), Math.abs(screenHeight), 0);
        if(rootNode){
            let mgr = rootNode.addComponent(UIMgr)
            UIMgr.instance = mgr;
            rootNode.children.forEach((node)=>{
                let nName = node.name
                if(mgr.layers.has(nName)){
                    warn("ui 层级重复："+nName)
                    return
                }
                mgr.layers.set(nName,node)
                mgr.layerStacks.set(nName,[])
            })
            UIMgr.instance.tipsLayerName = tipsLayerName
            UIMgr.ins.tipsLayerNode = UIMgr.ins.layers.get(tipsLayerName)
            director.addPersistRootNode(rootNode)
            return
        }
        error("UI根节点为null，无法进行初始化")
        // 创建层级节点
        // this.mainLayer = this.createLayer("MainLayer");
        // this.popLayer = this.createLayer("PopLayer");
        // this.tipsLayer = this.createLayer("TipsLayer");
        // this.marqueeLayer = this.createLayer("MarqueeLayer");
        // this.topLayer = this.createLayer("Top");

        // 将UIManager设置为常驻节点
        // director.addPersistRootNode(this.node);

    }

    // 创建层级节点
    private createLayer(name: string): Node {
        const layer = new Node();
        layer.name = name;
        layer.setPosition(new Vec3(0,0,0))
        let widget = layer.addComponent(Widget)
        widget.left = 0;
        widget.right = 0;

        // 设置 Widget 的 top 和 bottom 为 0，实现垂直布满
        widget.top = 0;
        widget.bottom = 0;

        // 设置 Widget 的对齐方式为水平和垂直都对齐
        widget.isAlignLeft = true;
        widget.isAlignRight = true;
        widget.isAlignTop = true;
        widget.isAlignBottom = true;

        // 更新 Widget
        widget.updateAlignment();
        layer.setParent(this.node); // 将层级节点作为UIManager的子节点
        return layer;
    }

    // 显示UI
    public async showUI(uiName: string, afterShowCb?: () => void, ...args: any[]) {
        const uiInfo = this.viewInfos[uiName]
        if (!uiInfo) {
            error(`view info not found for: ${uiName}`);
            return;
        }
        if(!this.layers.has(uiInfo.layer)){
            error("未知ui层级："+uiInfo.layer)
            return
        }
        let stack = this.layerStacks.get(uiInfo.layer)
        let exist = null;
        if(uiInfo.single){
            exist = stack.find(v=>(v as Component).name==uiName)
        }
        let view:View = null;
        if(!exist){
            // 加载预制件
            const uiNode = await this.loadUIPrefab(uiInfo.prefabPath);
            if (!uiNode) {
                error(`Failed to load UI: ${uiName}`);
                return;
            }

            // 添加UI脚本
            view = uiNode.addComponent(uiInfo.script) as View;

        }
        stack.push(view)
        let layerNode= this.layers.get(uiInfo.layer)
        this.beforeShowFun?.(layerNode,view,stack)
        view.node.setParent(layerNode)
        // 显示UI
        await view.showView(...args);
        // 执行回调函数
        afterShowCb?.();
    }

    public async releaseUI(uiName:string){//释放ui，从栈中移除

    }


    public async closeUI(uiName:string){

    }

    // 加载UI预制件
    private async loadUIPrefab(prefabPath: string): Promise<Node> {
        return new Promise((resolve, reject) => {
            resources.load(prefabPath, Prefab, (err, prefab) => {
                if (err) {
                    error(err);
                    resolve(null);
                } else {
                    const uiNode = instantiate(prefab);
                    resolve(uiNode);
                }
            });
        });
    }
    public async canShowTips(){
        if(!this.tipsLayerName){
            LogMgr.err("tips 层级未设置")
            return false
        }
        if(this.tipsLayerNode==null){
            error("tips 层级不存在："+this.tipsLayerName)
            return false
        }
        if(this.tipsPrefab==null){
            this.tipsPrefab = await new Promise((r,j)=>{
                resources.load("prefab/ui/compoents/tips",(e,data)=>{
                    if(e){
                        r(null)
                        LogMgr.err("加载tips预制件失败！",e)
                        return
                    }
                    r(data as Prefab)
                })
            })
        }
        if(this.tipsPrefab==null){
            return false;
        }
        return true
    }
    public async  showErrorTips(tips:string){
        let canDo = await this.canShowTips()
        if(!canDo){
            return
        }
        if(this.tipsPrefab==null){
            return
        }
        let tipsIns = instantiate(this.tipsPrefab)
        let tipsCom = tipsIns.getComponent(Tips)
        tipsCom.setErrorText(tips)
        this.tipsLayerNode.addChild(tipsIns)
    }
    public async  showSuccessTips(tips:string){
        let canDo = await this.canShowTips()
        if(!canDo){
            return
        }
        if(this.tipsPrefab==null){
            return
        }
        let tipsIns = instantiate(this.tipsPrefab)
        let tipsCom = tipsIns.getComponent(Tips)
        tipsCom.setSuccessText(tips)
        this.tipsLayerNode.addChild(tipsIns)
    }
    public async  showTips(tips:string){
        let canDo = await this.canShowTips()
        if(!canDo){
            return
        }
        if(this.tipsPrefab==null){
            return
        }
        let tipsIns = instantiate(this.tipsPrefab)
        let tipsCom = tipsIns.getComponent(Tips)
        tipsCom.setInfoText(tips)
        this.tipsLayerNode.addChild(tipsIns)
    }
}